package com.example.tic_tac_toe_in_android.view;

import java.util.Observable;
import java.util.Observer;

import com.example.tic_tac_toe_in_android.R;
import com.example.tic_tac_toe_in_android.model.HumanPlayer;
import com.example.tic_tac_toe_in_android.model.Position;
import com.example.tic_tac_toe_in_android.model.TicTacToeGame;
//import com.google.android.maps.MyLocationOverlay;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;

public class BoardActivity extends Activity implements OnClickListener,
		SensorEventListener, Observer {

	private static HumanPlayer player1;
	private static HumanPlayer player2;
	private static TicTacToeGame ticTacToeGame;

	private static Position position;

	// TextViews
	TextView tVPlayerOneName;
	TextView tVPlayerTwoName;
	TextView tVPlayerStatus;
	TextView tVNewGame;

	// buttons
	private Button bTRetry;

	private static ImageButton[][] boardRepesentation = new ImageButton[3][3];

	ImageButton currentClickBT = null;

	// Sensors
	private SensorManager mSensorManager;
	private Sensor mSensor;
	private final int rate = 250000; // 4 times in a second

	private float mAccel; // acceleration apart from gravity
	private float mAccelCurrent; // current acceleration including gravity
	private float mAccelLast; // last acceleration including gravity

	// SharedPreferences
	// private final String PREFS = "com.example.tic_tac_toe_in_android.view";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_board);
		allComponentInit();

		// get a reference to the sensor service
		mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		// checks whether there's a accelerometer on a device:
		if (mSensor != null) {
			Log.d("MyLog", "Yes U have a sensor TYPE_ACCELEROMETER");
			mSensorManager.registerListener(this, mSensor, rate);
			mAccel = 0.00f;
			mAccelCurrent = SensorManager.GRAVITY_EARTH;
			mAccelLast = SensorManager.GRAVITY_EARTH;

		} else {
			Log.d("MyLog", "sensor TYPE_ACCELEROMETER does Not exist");
		}

		if (savedInstanceState == null) {
			player1 = new HumanPlayer("Tyson");
			player2 = new HumanPlayer("ALI");
			// ticTacToeGame = TicTacToeGame.getInstance(player1, player2);
			ticTacToeGame = new TicTacToeGame(player1, player2);
		}

		// adding this activity to the observer of the tictactoeGame
		ticTacToeGame.addObserver(this);
		player1.setName(getIntent().getExtras().getString("playerOneName"));
		player2.setName(getIntent().getExtras().getString("playerTwoName"));
		tVPlayerOneName.setText(player1.getName() + "  " + player1.getScore());
		tVPlayerTwoName.setText(player2.getName() + "  " + player2.getScore());
		tVPlayerStatus.setText("");
		tVNewGame.setVisibility(View.INVISIBLE);
		bTRetry.setVisibility(View.INVISIBLE);

		ticTacToeGame.updateGame();
		updateMyboard();

	}

	@Override
	protected void onPause() {
		super.onPause();
		// unregister a sensor's listener to save battery
		if (mSensorManager != null) {
			mSensorManager.unregisterListener(this);
		}
	}

	private void allComponentInit() {
		boardinit();
		tVNewGame = (TextView) findViewById(R.id.TVNewGame);
		tVPlayerOneName = (TextView) findViewById(R.id.TVPlayerOneName);
		tVPlayerTwoName = (TextView) findViewById(R.id.TVPlayerTwoName);
		tVPlayerStatus = (TextView) findViewById(R.id.TVPlayerStatus);
		bTRetry = (Button) findViewById(R.id.BTRetry);
		bTRetry.setOnClickListener(this);

	}

	/*
	 * the board with 9 image buttons on
	 */
	private void boardinit() {

		boardRepesentation[0][0] = (ImageButton) findViewById(R.id.IB0X0);
		boardRepesentation[0][1] = (ImageButton) findViewById(R.id.IB0X1);
		boardRepesentation[0][2] = (ImageButton) findViewById(R.id.IB0X2);

		boardRepesentation[1][0] = (ImageButton) findViewById(R.id.IB1X0);
		boardRepesentation[1][1] = (ImageButton) findViewById(R.id.IB1X1);
		boardRepesentation[1][2] = (ImageButton) findViewById(R.id.IB1X2);

		boardRepesentation[2][0] = (ImageButton) findViewById(R.id.IB2X0);
		boardRepesentation[2][1] = (ImageButton) findViewById(R.id.IB2X1);
		boardRepesentation[2][2] = (ImageButton) findViewById(R.id.IB2X2);

		for (int row = 0; row < boardRepesentation.length; row++) {
			for (int column = 0; column < boardRepesentation[row].length; column++) {
				boardRepesentation[row][column].setOnClickListener(this);

			}
		}

	}

	private void setEnabledAllImageButtons(boolean enabled) {
		for (int row = 0; row < boardRepesentation.length; row++) {
			for (int column = 0; column < boardRepesentation[row].length; column++) {
				boardRepesentation[row][column].setEnabled(enabled);
			}
		}

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.IB0X0:
			currentClickBT = boardRepesentation[0][0];
			position = new Position(0, 0);

			break;
		case R.id.IB0X1:
			currentClickBT = boardRepesentation[0][1];
			position = new Position(0, 1);

			break;
		case R.id.IB0X2:
			currentClickBT = boardRepesentation[0][2];
			position = new Position(0, 2);

			break;
		case R.id.IB1X0:
			currentClickBT = boardRepesentation[1][0];
			position = new Position(1, 0);

			break;
		case R.id.IB1X1:
			currentClickBT = boardRepesentation[1][1];
			position = new Position(1, 1);

			break;
		case R.id.IB1X2:
			currentClickBT = boardRepesentation[1][2];
			position = new Position(1, 2);

			break;
		case R.id.IB2X0:
			currentClickBT = boardRepesentation[2][0];
			position = new Position(2, 0);

			break;
		case R.id.IB2X1:
			currentClickBT = boardRepesentation[2][1];
			position = new Position(2, 1);

			break;
		case R.id.IB2X2:
			currentClickBT = boardRepesentation[2][2];
			position = new Position(2, 2);

			break;
		case R.id.BTRetry:
			resetGame();
			break;

		default:
			Log.d("MyLog", "Error in the BoardActivityClass, onClick method");
			break;
		}
		ticTacToeGame.Move(position);
		updateMyboard();

	}

	public void updateMyboard() {
		// Log.d("MyLog", "updateMyboard");

		for (int row = 0; row < boardRepesentation.length; row++) {
			for (int column = 0; column < boardRepesentation[row].length; column++) {

				if (ticTacToeGame.board.getMyboard()[row][column].getSymbol() == 'X') {
					boardRepesentation[row][column]
							.setImageResource(R.drawable.cross);
					boardRepesentation[row][column].setEnabled(false);
				} else if (ticTacToeGame.board.getMyboard()[row][column]
						.getSymbol() == 'O') {
					boardRepesentation[row][column]
							.setImageResource(R.drawable.dot);
					boardRepesentation[row][column].setEnabled(false);

				} else if (ticTacToeGame.board.getMyboard()[row][column]
						.getSymbol() == 'E') {
					boardRepesentation[row][column].setImageResource(0);
					// boardRepesentation[row][column].setEnabled(true);
				}

			}
		}

	}

	/*
	 * reset The Game
	 */
	private void resetGame() {
		ticTacToeGame.reset();
		position = null;
		setEnabledAllImageButtons(true);
		tVNewGame.setVisibility(View.INVISIBLE);
		bTRetry.setVisibility(View.INVISIBLE);

	}

	@Override
	public void update(Observable observable, Object data) {

		try {
			tVPlayerStatus.setText("Winner is "
					+ ticTacToeGame.getWinnerPlayer().getName());

			tVPlayerOneName.setText(player1.getName() + "  "
					+ player1.getScore());
			tVPlayerTwoName.setText(player2.getName() + "  "
					+ player2.getScore());

			setEnabledAllImageButtons(false);
			bTRetry.setVisibility(View.VISIBLE);
			tVNewGame.setVisibility(View.VISIBLE);

			SaveScore();

		} catch (Exception e) {
			System.out.println("No Winner Player");
			tVPlayerStatus.setText("");
		}

		if (ticTacToeGame.referee.isDraw()) {
			tVPlayerStatus.setText(" Draaaaaaaaaaaw");
			bTRetry.setVisibility(View.VISIBLE);
			tVNewGame.setVisibility(View.VISIBLE);
			setEnabledAllImageButtons(false);
		}

	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		int sensorType = event.sensor.getType();

		if (sensorType == Sensor.TYPE_ACCELEROMETER) {

			float x = event.values[0];
			float y = event.values[1];
			float z = event.values[2];
			mAccelLast = mAccelCurrent;
			mAccelCurrent = (float) Math.sqrt((double) (x * x + y * y + z * z));
			float delta = mAccelCurrent - mAccelLast;
			mAccel = mAccel * 0.9f + delta; // perform low-cut filter

			if (mAccel > 3) {
				onShake();

			}

		}

	}

	/*
	 * 
	 */
	public void onShake() {
		Log.d("MyLog", "" + mAccel);
		resetGame();
		updateMyboard();
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {

	}

	public void SaveScore() {
		String temp = player1.toString() + " VS. " + player2.toString();
		GameSharedPreferences.save(this, temp);

	}
}
